//! 事件监听
use super::*;
use std::collections::HashMap;

#[wasm_bindgen]
pub struct Events {
    handlers: HashMap<String, Vec<js_sys::Function>>,
}

#[wasm_bindgen]
impl Events {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Self {
        Self {
            handlers: HashMap::new(),
        }
    }

    pub fn on(&mut self, name: String, callback: js_sys::Function) {
        if self.handlers.get_mut(&name).is_none() {
            self.handlers.insert(name.clone(), Vec::new());
        }

        self.handlers.get_mut(&name).unwrap().push(callback);
    }

    pub fn emit(&self, name: String, args: JsValue) {
        match self.handlers.get(&name) {
            Some(js_events) => {
                for x in js_events {
                    x.call1(&x, &args).unwrap();
                }
            }
            None => {}
        }
    }

    pub fn off(&mut self, name: String, callback: Option<js_sys::Function>) {
        match self.handlers.get_mut(&name) {
            Some(js_events) => {
                if callback.is_some() {
                    let mut list = vec![];
                    let callback = callback.unwrap();
                    for f in js_events.iter() {
                        if callback.ne(f) {
                            list.push(f.clone());
                        }
                    }

                    *js_events = list;
                } else {
                    self.handlers.remove(&name);
                }
            }
            None => {}
        }
    }
}
